namespace ThingsGateway.Foundation
{
    public static class ContainerExtensions
    {
        #region Public Methods

        /// <summary>
        /// 注册区域映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IContainer RegisterScoped<TFrom, TTO>(this IContainer service)
             where TFrom : class
             where TTO : class, TFrom
        {
            service.RegisterScoped(typeof(TFrom), typeof(TTO));
            return service;
        }

        /// <summary>
        /// 注册区域映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IContainer RegisterScoped<TFrom>(this IContainer service)
             where TFrom : class
        {
            service.RegisterScoped(typeof(TFrom), typeof(TFrom));
            return service;
        }

        /// <summary>
        /// 注册区域映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterScoped<TFrom, TTO>(this IContainer service, string key)
             where TFrom : class
             where TTO : class, TFrom
        {
            service.RegisterScoped(typeof(TFrom), typeof(TTO), key);
            return service;
        }

        /// <summary>
        /// 注册区域映射
        /// </summary>
        /// <param name="service"></param>
        /// <param name="fromType"></param>
        /// <param name="toType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterScoped(this IContainer service, Type fromType, Type toType, string key = "")
        {
            service.Register(new ServiceDescriptor(fromType, toType, Lifetime.Scoped), key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        /// <param name="service"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom, TTo>(this IContainer service, TTo instance)
              where TFrom : class
              where TTo : class, TFrom
        {
            service.RegisterSingleton(typeof(TFrom), instance);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <param name="service"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton(this IContainer service, object instance)
        {
            if (instance is null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            service.RegisterSingleton(instance.GetType(), instance);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom, TTo>(this IContainer service, string key, TTo instance)
              where TFrom : class
              where TTo : class, TFrom
        {
            service.RegisterSingleton(typeof(TFrom), instance, key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <param name="service"></param>
        /// <param name="fromType"></param>
        /// <param name="instance"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton(this IContainer service, Type fromType, object instance, string key = "")
        {
            service.Register(new ServiceDescriptor(fromType, instance), key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <param name="service"></param>
        /// <param name="instance"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom>(this IContainer service, object instance, string key = "")
        {
            service.Register(new ServiceDescriptor(typeof(TFrom), instance), key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom>(this IContainer service, string key = "")
        {
            service.Register(new ServiceDescriptor(typeof(TFrom), typeof(TFrom), Lifetime.Singleton), key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <param name="service"></param>
        /// <param name="fromType"></param>
        /// <param name="toType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton(this IContainer service, Type fromType, Type toType, string key = "")
        {
            service.Register(new ServiceDescriptor(fromType, toType, Lifetime.Singleton), key);
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom, TTO>(this IContainer service)
             where TFrom : class
             where TTO : class, TFrom
        {
            service.RegisterSingleton(typeof(TFrom), typeof(TTO));
            return service;
        }

        /// <summary>
        /// 注册单例
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterSingleton<TFrom, TTO>(this IContainer service, string key)
             where TFrom : class
             where TTO : class, TFrom
        {
            service.RegisterSingleton(typeof(TFrom), typeof(TTO), key);
            return service;
        }

        /// <summary>
        /// 注册临时映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IContainer RegisterTransient<TFrom, TTO>(this IContainer service)
             where TFrom : class
             where TTO : class, TFrom
        {
            service.RegisterTransient(typeof(TFrom), typeof(TTO));
            return service;
        }

        /// <summary>
        /// 注册临时映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IContainer RegisterTransient<TFrom>(this IContainer service)
             where TFrom : class
        {
            service.RegisterTransient(typeof(TFrom), typeof(TFrom));
            return service;
        }

        /// <summary>
        /// 注册临时映射
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTO"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterTransient<TFrom, TTO>(this IContainer service, string key)
            where TFrom : class
            where TTO : class, TFrom
        {
            service.RegisterTransient(typeof(TFrom), typeof(TTO), key);
            return service;
        }

        /// <summary>
        /// 注册临时映射
        /// </summary>
        /// <param name="service"></param>
        /// <param name="fromType"></param>
        /// <param name="toType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer RegisterTransient(this IContainer service, Type fromType, Type toType, string key = "")
        {
            service.Register(new ServiceDescriptor(fromType, toType, Lifetime.Transient), key);
            return service;
        }
        /// <summary>
        /// 创建类型对应的实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="service"></param>
        /// <param name="ps"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Resolve<T>(this IContainerProvider service, object[] ps, string key = "")
        {
            return (T)service.Resolve(typeof(T), ps, key);
        }

        /// <summary>
        /// 创建类型对应的实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="service"></param>
        /// <returns></returns>
        public static T Resolve<T>(this IContainerProvider service)
        {
            return service.Resolve<T>(null);
        }

        /// <summary>
        /// 创建类型对应的实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Resolve<T>(this IContainerProvider service, string key)
        {
            return service.Resolve<T>(null, key);
        }

        /// <summary>
        /// 移除注册信息
        /// </summary>
        /// <param name="service"></param>
        /// <param name="fromType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer Unregister(this IContainer service, Type fromType, string key = "")
        {
            service.Unregister(new ServiceDescriptor(fromType), key);
            return service;
        }

        /// <summary>
        /// 移除注册信息
        /// </summary>
        /// <param name="service"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static IContainer Unregister<TFrom>(this IContainer service, string key = "")
        {
            service.Unregister(new ServiceDescriptor(typeof(TFrom)), key);
            return service;
        }

        #endregion Public Methods

    }
}